/////////////////////////////////////////////////////////////////////////////
// Name:        socket_gethostbyname.h
// Purpose:     
// Author:      yangfuqiang
// Modified by: 
// Created:     2015-03-12 09:32:01 
// RCS-ID:      
// Copyright:   
// Licence:     
/////////////////////////////////////////////////////////////////////////////
#ifndef _SOCKET_GETHOSTBYNAME_H_
#define _SOCKET_GETHOSTBYNAME_H_
#include "core/common_types.h"
#include "core/system/thread_wrapper.h"
#include "core/system/critical_section_wrapper.h"
#include "core/system/atomic32.h"
#include "core/system/event_wrapper.h"
#include <string>
#include <vector>
#include <map>
#include "socket_host_table.h"
namespace qb
{
	typedef std::vector<std::string> iptable;
	typedef std::vector<CChar32> ipCtable;
	class hosttable
	{
	public:
		hosttable()
			: m_hosttable_crit(*CriticalSectionWrapper::CreateCriticalSection()),m_uUpdatedTime(0)
		{

		}
		virtual ~hosttable()
		{
			delete& m_hosttable_crit;
		}
		int get_iptable(iptable& ips, const char* host)
		{
			CriticalSectionScoped lock(&m_hosttable_crit);
			CChar32 cHost(host);
			htable::iterator it = m_htable.find(cHost);
			if (it != m_htable.end())
			{
				ips.clear();
				for (uint32_t i = 0;i< it->second.size(); i++)
				{
					ips.push_back(it->second.at(i).getChar());
				}
				return 0;
			}

			return -1;
		}
		void add(const iptable& ips, const char* host)
		{
			CriticalSectionScoped lock(&m_hosttable_crit);
			ipCtable cpy;
			for (uint32_t i = 0;i< ips.size(); i++)
			{
				cpy.push_back(ips.at(i));
			}
			m_htable[host] = cpy;
		}
		void SetUpdatedTime();
		int64_t GetUpdatedTime(){ return m_uUpdatedTime;}
		void ClearHtable()
		{
			CriticalSectionScoped lock(&m_hosttable_crit);
			m_htable.clear();
		}
	private:
		typedef std::map<CChar32, ipCtable> htable;
		CriticalSectionWrapper&	m_hosttable_crit;
		htable m_htable;
		int64_t m_uUpdatedTime;
	};

	class CSocketGethostbyname
	{
	public:
		CSocketGethostbyname();
		virtual ~CSocketGethostbyname();
		int32_t GetHostByName(const char* host,bool force = false);
		int32_t WaitProcess(int32_t timeout_ms);
		int32_t CancelGetHostByName();
		int32_t GetNumOfIPAddress();
		int64_t GetMillisecondTimestamp();
		const char* GetIPAddress(int index);
		const char* GetFirstIPAddress();

	private:
		static bool ThreadFun(void* arg);
		bool ThreadRun(void* arg);
		void StopThread(ThreadWrapper** thread_);
		static bool IsHostTimeout();

	private:
		ThreadWrapper*					m_thread;
		EventWrapper&					m_event;
		Atomic32						m_run_flag;
		std::string						m_host;
		iptable							m_iptable;
		static hosttable				m_hosttable;
		CriticalSectionWrapper&			m_interface_crit;
	};
}

#endif // _SOCKET_GETHOSTBYNAME_H_
